package mygameserver;

import java.io.IOException;
import java.net.Socket;
import java.util.Vector;

public class ServerCommands {

    static Vector<GameLogic> games = new Vector<GameLogic>();

    public static void sendPlayerList(Socket clSocket) {
        String outp = CommandsList.UPDATE.getAbbr();
        for (Player p : GameServer.players) {
            if (!p.getcSocket().equals(clSocket)) {
                outp = outp + ";" + p.getpName() + ";" + p.getpHashCode();
            }
        }
        ServerThread.server.sendMessageTo(clSocket, outp);
    }

    public static void removePlayer(Socket clSocket) {
        Player needToRemove = null;
        for (Player p : GameServer.players) {
            if (p.getcSocket() == clSocket) {
                needToRemove = p;
                break;
            }
        }
        if (needToRemove != null) {
            ServerThread.server.removeObserver(needToRemove);
        }
    }
    
    public static void createConnection(Socket socket, String[] arg){
        Player player = new Player(socket, arg[1]);
        ServerThread.server.registerObserver(player);
    }

    public static void closeConnection(Socket clSocket) {
        ServerCommands.removePlayer(clSocket);

        try {
            clSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void createGame(String[] arg) {
        addGame(byHash(arg[1]), byHash(arg[2]));
    }

    public static void addGame(Player p1, Player p2) {
        GameLogic game = new GameLogic();
        game.registerObserver(p1);
        game.registerObserver(p2);
        ServerThread.server.removeObserver(p1);
        ServerThread.server.removeObserver(p2);
        game.setStart();
        games.add(game);
        Runnable r = new GameThread(game);
        Thread t = new Thread(r);
        t.start();
    }

    public static void receiveRequest(String[] arg, Socket clSocket) {
        for (Player p : GameServer.players) {
            if (p.getpHashCode() == Integer.parseInt(arg[1])) {
                ServerThread.server.sendMessageTo(p.getcSocket(), CommandsList.GAME_REQUEST.getAbbr() + ";" + clSocket.hashCode() + ";" + p.getpHashCode());
                break;
            }
        }
    }

    public static void receiveResume(String[] arg) {
        int gameIndex = Integer.parseInt(arg[1]);
        GameLogic game = games.get(gameIndex);
        int answer = Integer.parseInt(arg[2]);

        if (game.isResume() == -1) {
            ServerThread.server.registerObserver(game.getObservers().get(0));
            ServerThread.server.registerObserver(game.getObservers().get(1));
            Socket s1 = ((Player)game.getObservers().get(0)).getcSocket();
            Socket s2 = ((Player)game.getObservers().get(1)).getcSocket();
            sendPlayerList(s1);
            sendPlayerList(s2);

        } else if (game.isResume() == 1 && answer == 0) {
            game.setStart();

        } else if (answer == 1) {
            game.setResume(-1);

        } else if (game.isResume() == 0 && answer == 0) {
            game.setResume(1);
        }
    }

    public static void sendHashCode(Socket s) {
        ServerThread.server.sendMessageTo(s, CommandsList.HASH_CODE.getAbbr() + ";" + s.hashCode() + ";");
    }

    public static void receive(String a, Socket clSocket) {
        String[] arg = a.split("\\;");
        CommandsList comm = CommandsList.getCommand(arg[0]);

        switch (comm) {
            case CONNECT:
                createConnection(clSocket, arg);
                sendHashCode(clSocket);
                sendPlayerList(clSocket);
                break;
            case SET_CELL:
                GameCommands.receiveCell(arg);
                break;
            case GAME_REQUEST:
                receiveRequest(arg, clSocket);
                break;
            case APPROVE:
                createGame(arg);
                break;
            case GAME_RESUME:
                receiveResume(arg);
                break;
            case CLOSE_CONNECTION:
                closeConnection(clSocket);
                break;
        }
    }

    public static Player byHash(String stringHashCode) {
        Player player = null;
        for (Player p : GameServer.players) {
            if (p.getpHashCode() == Integer.parseInt(stringHashCode)) {
                player = p;
                break;
            }
        }
        return player;
    }
}
